package com.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.log4j.Logger;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.gateway.common.Common;
import com.gateway.core.MyBuffer;
import com.gateway.core.MyProtocol;

/**
 * 逻辑服务器
 * 
 * @author Simple
 * @date 2013-7-5 下午03:34:05
 * @Description TODO
 */
public class MyLogicServer {

  private Logger log=Logger.getLogger(this.getClass());

  private String logicServerName;// LogicServer名称

  private int port;// 端口

  private String type;// 类型

  private NioSocketAcceptor acceptor;// 接收者

  private NioSocketConnector connector;// 连接者

  private MyLogicServerHandler myLogicServerHandler;// server handler

  private MyLogicClientHandler myLogicClientHandler;// client handler

  public MyLogicServer(String logicServerName, int port, String type) {
    this.logicServerName=logicServerName;
    this.port=port;
    this.type=type;
  }

  public static void main(String[] args) {
    for(int i=1; i <= 1; i++) {
      String name="LOGIC_SERVER_1000";
      int port=10000;
      String type="运行";
      MyLogicServer server=new MyLogicServer(name + i, port + i, type + i);
      server.startLogicServer();
    }
  }

  /**
   * 启动逻辑服务器
   * 
   * @param port
   * @param logicServerName
   * @param status
   */
  public void startLogicServer() {
    log.debug("startup ...");
    acceptor=new NioSocketAcceptor();
    DefaultIoFilterChainBuilder chain=acceptor.getFilterChain();
    chain.addLast("LogicServerProtocolFilter", new ProtocolCodecFilter(new MyLogicServerProtocolCodecFactory(Charset
      .forName("utf-8"))));
    // set myLogicServerHandler
    myLogicServerHandler=new MyLogicServerHandler(this);
    acceptor.setHandler(myLogicServerHandler);
    // set sessionConfig
    acceptor.getSessionConfig().setReadBufferSize(1024 * 10);
    try {
      acceptor.bind(new InetSocketAddress(port));
      log.debug(logicServerName + " started ! PORT=" + port);
      // 连接网关
      connectionGateway(Common.PORT_GATEWAY);
    } catch(IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 连接网关
   * 
   * @param logicServerName
   * @param status
   * @param gatewayPort
   * @param selfPort
   */
  public void connectionGateway(int gatewayPort) {
    log.debug("connect gateway ...");
    connector=new NioSocketConnector();
    DefaultIoFilterChainBuilder chain=connector.getFilterChain();
    chain.addLast("encoderFilter", new ProtocolCodecFilter(new MyLogicServerProtocolCodecFactory(Charset.forName("utf-8"))));
    myLogicClientHandler=new MyLogicClientHandler(this);
    connector.setHandler(myLogicClientHandler);
    ConnectFuture cf=connector.connect(new InetSocketAddress("localhost", gatewayPort));
    cf.awaitUninterruptibly();
    log.debug("connect gateway success!");
    sendRegisterMessage(cf);
  }

  /**
   * 发送注册信息
   * 
   * @param cf
   */
  private void sendRegisterMessage(ConnectFuture cf) {
    // 封装bodyData
    MyBuffer buffer=MyBuffer.allocate(100);
    buffer.putString(logicServerName);
    buffer.putString(type);
    buffer.putInt(port);
    buffer.flip();
    // 封装MyProtocol
    MyProtocol myProtocol=new MyProtocol(Common.REQ_REGISTER2GATEWAY, buffer.getIoBuffer());
    cf.getSession().write(myProtocol);
  }

  /**
   * 重新连接
   */
  public boolean reconnection(IoSession session) {
    log.debug("LogicServer-Connector管理Session个数：" + connector.getManagedSessionCount());
    ConnectFuture cf=connector.connect(session.getRemoteAddress());
    cf.awaitUninterruptibly();
    if(cf.isConnected()) {
      log.debug("reconnect gateway success!");
      sendRegisterMessage(cf);
      return true;
    } else {
      log.debug("reconnect gateway faild");
      return false;
    }
  }

  public void shutDownConnector() {
    log.debug("关闭Connector");
    connector.dispose();
  }

  public void shutDownAcceptor() {
    log.debug("关闭Acceptor");
    acceptor.dispose();
  }

  public void setMyLogicServerHandler(MyLogicServerHandler myLogicServerHandler) {
    this.myLogicServerHandler=myLogicServerHandler;
  }

  public MyLogicServerHandler getMyLogicServerHandler() {
    return myLogicServerHandler;
  }

  public void setAcceptor(NioSocketAcceptor acceptor) {
    this.acceptor=acceptor;
  }

  public NioSocketAcceptor getAcceptor() {
    return acceptor;
  }

  public void setConnector(NioSocketConnector connector) {
    this.connector=connector;
  }

  public NioSocketConnector getConnector() {
    return connector;
  }

  public void setLogicServerName(String logicServerName) {
    this.logicServerName=logicServerName;
  }

  public String getLogicServerName() {
    return logicServerName;
  }

  public void setPort(int port) {
    this.port=port;
  }

  public int getPort() {
    return port;
  }

  public void setType(String type) {
    this.type=type;
  }

  public String getType() {
    return type;
  }

  public void setMyLogicClientHandler(MyLogicClientHandler myLogicClientHandler) {
    this.myLogicClientHandler=myLogicClientHandler;
  }

  public MyLogicClientHandler getMyLogicClientHandler() {
    return myLogicClientHandler;
  }
}
